<?php
/**
 * Created by 荣耀电竞.
 * User: 林子彦 <278805354@qq.com>
 * Date: 2018/6/13 0013
 * Time: 10:12
 */

namespace App\Content\Repositories;


use App\Content\Contracts\WxUsersInterface;
use App\Content\Exceptions\ContentException;
use App\Content\Models\InfoCollectionModel;
use App\Content\Models\InfoCommentsModel;
use App\Content\Models\SendCodeModel;
use App\Content\Models\WxUserFollowModel;
use App\Content\Models\WxUsersModel;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Request;

class DbWxUsersRepository implements WxUsersInterface
{

    /***
     * 用户模型
     * @return WxUsersModel
     */
    public function getWxUsersModel()
    {
        return app()->make(WxUsersModel::class);
    }

    /**
     * 发送短信码
     * @return SendCodeModel
     */
    public function getSendCodeModel()
    {
        return app()->make(SendCodeModel::class);
    }
    /**
     * 评论模型
     * @return InfoCommentsModel
     */
    public function getInfoCommentsModel(){
        return app()->make(InfoCommentsModel::class);
    }

    /**
     * 文章收藏模型
     * @return InfoCollectionModel
     */
    public function getInfoCollectionModel(){
        return app()->make(InfoCollectionModel::class);
    }

    /**
     * 关注模型
     * @return WxUserFollowModel
     */
    public function getWxUserFollowModel()
    {
        return app()->make(WxUserFollowModel::class);
    }
    /**
     * 第三方登陆
     * @param $data
     * @return mixed|void
     */
    public function thridLogin($data)
    {


        if ($userData = $this->getWxUsersModel()->newQuery()->updateOrCreate(["openid" => $data['openid']], $data)) {
            $token = $this->genToken(32, true, $userData->uid);
            return $token;
        }

    }

    /**
     * 手机号注册
     * @param $data
     * @return mixed|void
     */
    public function mobileLogin($data)
    {

        $info = $this->getWxUsersModel()->newQuery()->where("openid", $data["mobile"])->first();
        if (empty($info)) {
            throw new ContentException(ContentException::EROOR_USER_LOGIN_ACCOUNT);
        }
        if ($info->password != lqw_ucenter_md5($data['password'])) {
            throw new ContentException(ContentException::EROOR_USER_LOGIN_PASSWORD);
        }
        $token = $this->genToken(32, true, $info->uid);
        return $token;
    }
    /**
     * 获取用户信息
     * @param $where
     * @return mixed|void
     */
    public function getUserInfo($where){
        $request=Request::instance();
        $select=empty($request->input("select")) ? '*' : explode(",",$request->input("select"));
        return $this->getWxUsersModel()->newQuery()->select($select)->where($where)->first();
    }

    /**
     * 手机号注册
     * @param $data
     * @return mixed|void
     */
    public function mobileReg($data)
    {

        $request = Request::instance();
        $st=time()-900;
        $info = $this->getSendCodeModel()->newQuery()->where("mobile", $data["mobile"])->where("update_time",">",$st)->first();
        if(empty($info)){
            throw new ContentException(ContentException::EROOR_MOBILE_CODE);
        }
        if ($request->input("code") !==$info->code ) {
            throw new ContentException(ContentException::EROOR_MOBILE_CODE);
        }
        unset($data["code"]);
        $returnArr = [];
        $returnArr["openid"] = $data["mobile"];
        $returnArr["password"] = lqw_ucenter_md5($data["password"]);
        if ($userData = $this->getWxUsersModel()->newQuery()->updateOrCreate(["openid" => $returnArr['openid']], $returnArr)) {
            $token = $this->genToken(32, true, $userData->uid);

            return $token;
        }
    }

    /**
     * 修改密码
     * @param $data
     * @return mixed|void
     * @throws ContentException
     */

    public function updateUserPassword($data){
        $request = Request::instance();
        $st=time()-900;
        $info = $this->getSendCodeModel()->newQuery()->where("mobile", $data["mobile"])->where("update_time",">",$st)->first();
        if(empty($info)){
            throw new ContentException(ContentException::EROOR_MOBILE_CODE);
        }
        if ($request->input("code") !==$info->code ) {
            throw new ContentException(ContentException::EROOR_MOBILE_CODE);
        }
        unset($data["code"]);
        $where["openid"]=$data["mobile"];
        $where["uid"]=AUID;
        $isExit=$this->getWxUsersModel()->newQuery()->where($where)->exists();
        if(!$isExit){
            throw new ContentException(ContentException::EROOR_USER_LOGIN_ACCOUNT);
        }
        return $this->getWxUsersModel()->newQuery()->where("uid",AUID)->update(["password"=>lqw_ucenter_md5($data['password'])]);

    }


    /**
     * 发送短信
     * @param $data
     * @return mixed|void
     */
    public function sendSmsCode($data)
    {
        $st=time()-900;
        $info = $this->getSendCodeModel()->newQuery()->where("mobile", $data["mobile"])->where("update_time",">",$st)->first();
        if ($info) {
            throw  new  ContentException(ContentException::EROOR_MOBILE_TIME_CODE);
        }

        $randnum = rand(1000, 9999);
        if ($this->sendCode($data["mobile"], $randnum)) {
            $data["code"] = $randnum;
            return $this->getSendCodeModel()->newQuery()->updateOrCreate(["mobile" => $data["mobile"]], $data);
            //将发送码送到数据库去
        } else {
           throw  new ContentException(ContentException::EROOR_MOBILE_SEND_CODE);
        }
    }

    /**
     * 获取我的收藏
     * @param $where
     * @return mixed|void
     */
    public function getUserMyCollection($where){
        $request = Request::instance();
        $limit = empty($request->input("limit")) ? 10 : $request->input("limit");
        $sort = empty($request->input("sort")) ? 'create_time' : $request->input("sort");
        $order = empty($request->input("order")) ? 'desc' : $request->input("order");
        $select=empty($request->input("select")) ? '*' : explode(",",$request->input("select"));
        $select2=empty($request->input("select2")) ? '*' : explode(",",$request->input("select2"));
        return  $this->getInfoCollectionModel()->newQuery()->select($select)->with(["article"=>function($query) use($select2){
            $query->select($select2);
        }])->where($where)->orderBy($sort, $order)->paginate($limit);

    }

    /**
     * 获取我的评论
     * @param $where
     * @return mixed|void
     */
    public function getUserMyComment($where){
        $request = Request::instance();
        $limit = empty($request->input("limit")) ? 10 : $request->input("limit");
        $sort = empty($request->input("sort")) ? 'create_time' : $request->input("sort");
        $order = empty($request->input("order")) ? 'desc' : $request->input("order");
        $select=empty($request->input("select")) ? '*' : explode(",",$request->input("select"));
        $select2=empty($request->input("select2")) ? '*' : explode(",",$request->input("select2"));
        return  $this->getInfoCommentsModel()->newQuery()->select($select)->with(["article"=>function($query) use($select2){
            $query->select($select2);
        }])->where($where)->orderBy($sort, $order)->paginate($limit);
    }

    public function setUserFollow($data){
        $data["uid"]=AUID;
        $isExits=$this->getWxUserFollowModel()->newQuery()->where($data)->exists();
        if($isExits){
            return $this->getWxUserFollowModel()->newQuery()->where($data)->delete();
        }
        return $this->getWxUserFollowModel()->newQuery()->create($data);
    }

    /**
     * 获取我的关注
     * @param $where
     * @return mixed|void
     */
    public function getUserMyFollow($where){
        $request = Request::instance();
        $limit = empty($request->input("limit")) ? 10 : $request->input("limit");
        $sort = empty($request->input("sort")) ? 'create_time' : $request->input("sort");
        $order = empty($request->input("order")) ? 'desc' : $request->input("order");
        $select=empty($request->input("select")) ? '*' : explode(",",$request->input("select"));
        $select2=empty($request->input("select2")) ? '*' : explode(",",$request->input("select2"));
        return  $this->getWxUserFollowModel()->newQuery()->select($select)->with(["user"=>function($query) use($select2){
            $query->select($select2);
        }])->where($where)->orderBy($sort, $order)->paginate($limit);
    }

    /**
     * 用户昵称
     * @param $data
     * @return mixed|void
     */
    public function updateUser($data){
      return $this->getWxUsersModel()->newQuery()->where("uid",AUID)->update($data);
    }


    public function sendCode($phone, $randnum)
    {
        return true;
        $appid = '1400034522';
        $rand = rand(100000, 999999);
        $time = time();
        //$randnum = rand(1000, 9999);
        $url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms?sdkappid={$appid}&random={$rand}";
        //$sign = sha256(appkey=5f03a35d00ee52a21327ab048186a2c4&random=7226249334&time=1457336869&mobile=13788888888);
        $appkey = '68d468cef6d01ae5de22270d54b42c4f';
        $post = array(
            "tel" => array( //如需使用国际电话号码通用格式，如："+8613788888888" ，请使用sendisms接口见下注
                "nationcode" => "86", //国家码
                "mobile" => $phone, //手机号码
            ),
            "type" => 0, //0:普通短信;1:营销短信（强调：要按需填值，不然会影响到业务的正常使用）
            "msg" => $randnum . " 为您的登录验证码，请于1分钟内填写。如非本人操作，请忽略本短信。", //utf8编码，需要匹配审核通过的模板内容
            "sig" => $this->calculateSig($appkey, $rand, $time, $phone), //app凭证，具体计算方式见下注
            "time" => $time, //unix时间戳，请求发起时间，如果和系统时间相差超过10分钟则会返回失败
            "extend" => "", //通道扩展码，可选字段，默认没有开通(需要填空)。
            //在短信回复场景中，腾讯server会原样返回，开发者可依此区分是哪种类型的回复
            "ext" => "" //用户的session内容，腾讯server回包中会原样返回，可选字段，不需要就填空。
        );
        $res = json_decode($this->sendCurlPost($url, $post), true);

        if ($res['result'] == 0) {
            return true;
        } else {
            throw  new ContentException(ContentException::EROOR_MOBILE_SEND_CODE,["msg"=>$res['errmsg']]);
        }
    }

    public function calculateSig($appkey, $random, $curTime, $phoneNumbers)
    {
        $phoneNumbersString = $phoneNumbers;

        for ($i = 0; $i < strlen($phoneNumbers); $i++) {
            $phoneNumbersString .= ("," . $phoneNumbers[$i]);
        }

        return hash("sha256", "appkey=" . $appkey . "&random=" . $random
            . "&time=" . $curTime . "&mobile=" . $phoneNumbersString);
    }

    public function sendCurlPost($url, $dataObj)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($dataObj));
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        $ret = curl_exec($curl);
        if (false == $ret) {
            // curl_exec failed
            $result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
        } else {
            $rsp = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            if (200 != $rsp) {
                $result = "{ \"result\":" . -1 . ",\"errmsg\":\"" . $rsp
                    . " " . curl_error($curl) . "\"}";
            } else {
                $result = $ret;
            }
        }
        curl_close($curl);
        return $result;
    }

    /**
     * 获取一个token值
     * @param int $len 长度，默认32位
     * @param bool $md5 默认使用md5算法
     * @param int $uid 用户uid
     * @return string 一个32为的token串
     */
    function genToken($len = 32, $md5 = true, $uid = 0)
    {
        # Seed random number generator
        # Only needed for PHP versions prior to 4.2
        mt_srand((double)microtime() * 1000000);
        # Array of characters, adjust as desired
        $chars = array(
            'Q', '@', '8', 'y', '%', '^', '5', 'Z', '(', 'G', '_', 'O', '`',
            'S', '-', 'N', '<', 'D', '{', '}', '[', ']', 'h', ';', 'W', '.',
            '/', '|', ':', '1', 'E', 'L', '4', '&', '6', '7', '#', '9', 'a',
            'A', 'b', 'B', '~', 'C', 'd', '>', 'e', '2', 'f', 'P', 'g', ')',
            '?', 'H', 'i', 'X', 'U', 'J', 'k', 'r', 'l', '3', 't', 'M', 'n',
            '=', 'o', '+', 'p', 'F', 'q', '!', 'K', 'R', 's', 'c', 'm', 'T',
            'v', 'j', 'u', 'V', 'w', ',', 'x', 'I', '$', 'Y', 'z', '*'
        );
        # Array indice friendly number of chars;
        $numChars = count($chars) - 1;
        $token = '';
        # Create random token at the specified length
        for ($i = 0; $i < $len; $i++)
            $token .= $chars[mt_rand(0, $numChars)];
        # Should token be run through md5?
        if ($md5) {
            # Number of 32 char chunks
            $chunks = ceil(strlen($token) / 32);
            $md5token = '';
            # Run each chunk through md5
            for ($i = 1; $i <= $chunks; $i++)
                $md5token .= md5(substr($token, $i * 32 - 32, 32));
            # Trim the token
            $token = substr($md5token, 0, $len);
        }
        $arr = [];
        $arr['uid'] = $uid;
        $arr['token'] = $token;
        $string = json_encode($arr);

        Cache::forever($uid, $token);  //用户uid缓存起来
        return base64_encode($string);
    }




}